#pragma once

#ifndef MODIFIESHANDLE_H
#define MODIFIESHANDLE_H
#include "PKB.h"
#include "spa_types.h"
#include <vector>
#include <set>
#include <map>
#include <string>


using namespace std;
class PKB;


class ModifiesHandle
{
	
private: 
	PKB* pkb;
	ModifiesHandle(void);
	~ModifiesHandle(void);
	ModifiesHandle(const ModifiesHandle&);
	ModifiesHandle& operator=(const ModifiesHandle&);



	vector<vector<int>> ModStatementsGivenVar(const VARINDEX);
	vector<vector<int>> ModAssignmentsGivenVar(const VARINDEX);
	vector<vector<int>> ModIfGivenVar(const VARINDEX);
	vector<vector<int>> ModWhileGivenVar(const VARINDEX);
	vector<vector<int>> ModContainerGivenVar(const VARINDEX);
	vector<vector<int>> ModStatementsAndVars();
	vector<vector<int>> ModAssignmentsAndVars();
	vector<vector<int>> ModIfAndVar();
	vector<vector<int>> ModWhileAndVar();
	vector<vector<int>> ModContainerAndVar();
	vector<vector<int>> ModVarsGivenStatement(const int);
	vector<vector<int>> ModProcAndVars();
	vector<vector<int>> ModVarsGivenProc(const PROCINDEX);
	vector<vector<int>> ModProcGivenVar(const VARINDEX);
	bool MergeMultiVector(vector<vector<int>> &head, vector<vector<int>> tail);

	
public:

	// case 1: Modifies(all_s, 'x')
	// case 2: Modifies(all_a, 'x')
	// case 3: Modifies(all_if, 'x')
	// case 4: Modifies(all_while, 'x')
	// *     : Modifies(all_container, 'x')  
	// case 5: Modifies(all_s, all_v) -- can cache
	// case 6: Modifies(all_a, all_v) -- can cache
	// case 7: Modifies(all_if, all_v)
	// case 8: Modifies(all_while, all_v)
	// *     : Modifies(all_container, all_v)
	// case 9: Modifies(stmt_num, v)
	// case 10: Modifies(p, v)
	// case 11: Modifies('Main', v)
	// case 12: Modifies(p, 'x')

	vector<vector<int>> FetchValidModifiesStatementVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> FetchValidModifiesProcedureVar(vector<int> stmts_in, vector<int> vars_in);
			
	vector<vector<int>> GetStatementModifiesVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> GetAssignmentModifiesVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> GetIfModifiesVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> GetWhileModifiesVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> GetContainerModifiesUsesVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> GetProcedureModifiesVar(vector<int> stmts_in, vector<int> vars_in);




};



#endif